#ifndef KCP_H
#define KCP_H
#include "kcppacket.h"
#include "looplist.h"

#include <stdint.h>
#include <queue>
#include <list>
#include <set>

class KCPAgent;

using namespace std;
//typedef void (*actionFunc)();
//typedef void (*packetFunc)(shared_ptr<KCPPacket>);

class KCP {
public:
	bool IsClose = false;
	KCPAgent *kcpAgent;
	//actionFunc closeEventHandler;
	//packetFunc outputFunc;

	KCP() {
		winStart = 0;
		winEnd = windSz;
		ackWinStart = 0;
		ackWinEnd = windSz*2;
		recvList = shared_ptr<LoopList>(new LoopList(windSz));
	}

	void Send(shared_ptr< std::vector<unsigned char> > data);
	shared_ptr< KCPPacket > Recv();
	void Input(shared_ptr< std::vector<unsigned char> > data);
	void Update(double delta);
	void CloseKCP();

private:
	uint32_t sendId = 0;
	uint32_t windSz = 10;
	uint32_t winStart = 0;
	uint32_t winEnd;
	uint32_t ackWinStart = 0;
	uint32_t ackWinEnd = 6;
	double interval = 0.05;
	double accTime = 0;
	uint32_t maxRecvNum = 999;
	queue<shared_ptr<KCPPacket> > sendQueue;
	queue<shared_ptr<KCPPacket> > recvQueue;
	list<shared_ptr<KCPPacket> > sendBuf;
	queue<shared_ptr<KCPPacket> > recvBuf;
	set<uint32_t> ackYet;
	shared_ptr<LoopList> recvList;


	void PutPackInWindow();
	void Close();
	void SendWin();
	void HandleAcked();
	void HandleSend();
	bool CheckInWin(uint32_t id, uint32_t st, uint32_t end);
	void CheckLoopList();
	void HandleRecv();

	void outputFunc(shared_ptr<KCPPacket>);
	void closeEventHandler();


};
#endif
